package zhihuilan.config;

import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.netty.channel.ChannelOption;
import io.netty.handler.timeout.ReadTimeoutHandler;
import io.netty.handler.timeout.WriteTimeoutHandler;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.http.client.BufferingClientHttpRequestFactory;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.reactive.ReactorClientHttpConnector;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.netty.http.client.HttpClient;
import reactor.netty.resources.ConnectionProvider;
import zhihuilan.common.aspect.LogClientHttpInterceptor;

import javax.annotation.Resource;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.time.temporal.ChronoUnit;
import java.util.Collections;
import java.util.concurrent.TimeUnit;

@Configuration
public class RestClientConfig {

//    @Resource
//    private LogClientHttpInterceptor logClientHttpInterceptor;
//
//    @Resource
//    private ObjectMapper objectMapper;

//    @Bean
//    public RestClient.Builder restClientBuilder() {
//        return RestClient.builder()
//                .requestInterceptor(logClientHttpInterceptor)
//                //.defaultHeader("AUTHORIZATION", fetchToken())
//                //.messageConverters(...)
//                .requestFactory(clientHttpRequestFactory());
//    }
//
//    @Bean
//    public WebClient.Builder webClientBuilder() {
//        HttpClient httpClient = HttpClient.create(ConnectionProvider.create("webclient-webflux", 1000))
//                .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 30000)
//                .doOnConnected(connection -> connection.addHandlerLast(new ReadTimeoutHandler(3, TimeUnit.MINUTES))
//                        .addHandlerLast(new WriteTimeoutHandler(3, TimeUnit.MINUTES))
//                );
//        BufferingResponseConnector connector = new BufferingResponseConnector(new ReactorClientHttpConnector(httpClient));
//        return WebClient.builder()
//                // .exchangeFunction(new WebClientExchangeFunction(ExchangeFunctions.create(connector)))
//                .clientConnector(connector)
//                .filter(logClientHttpInterceptor);
//    }
//
//    @Bean
//    public RestClient restClient() {
//        return restClientBuilder().build();
//    }
//
//    @Bean
//    public ClientHttpRequestFactory clientHttpRequestFactory() {
//        ReactorNettyClientRequestFactory clientHttpRequestFactory = new ReactorNettyClientRequestFactory();
//        clientHttpRequestFactory.setConnectTimeout(Duration.of(30, ChronoUnit.SECONDS));
//        clientHttpRequestFactory.setReadTimeout(Duration.of(3, ChronoUnit.MINUTES));
//        clientHttpRequestFactory.setExchangeTimeout(Duration.of(3, ChronoUnit.MINUTES));
//        return new BufferingClientHttpRequestFactory(clientHttpRequestFactory);
//    }
//
//    @Bean
//    @LoadBalanced
//    public RestTemplate balancedRestTemplate() {
//        return new RestTemplateBuilder()
//                .requestFactory(this::clientHttpRequestFactory)
//                .interceptors(logClientHttpInterceptor)
//                .build();
//    }

    @Bean
    public RestTemplate restTemplate() {
        RestTemplate restTemplate = new RestTemplate();
        FastJsonHttpMessageConverter fastJsonHttpMessageConverter = new FastJsonHttpMessageConverter();
        fastJsonHttpMessageConverter.setSupportedMediaTypes(Collections.singletonList(MediaType.ALL));
        restTemplate.getMessageConverters().add(0, fastJsonHttpMessageConverter);
        restTemplate.getMessageConverters().add(new StringHttpMessageConverter(StandardCharsets.UTF_8));
        return restTemplate;
    }
}
